var validator = require('validator');
var eventproxy = require('eventproxy');
var config = require('../config');
var User = require('../proxy').User;
var mail = require('../common/mail');
var tools = require('../common/tools');
var utility = require('utility');
var authMiddleWare = require('../middlewares/auth');
var uuid = require('node-uuid');
var _ = require('lodash');
var S = require('string');

//sign up
exports.showSignup = function(req, res) {
    res.render('sign/signup');
};

exports.signup = function(req, res, next) {
    var loginname = validator.trim(req.body.loginname).toLowerCase();
    var email = validator.trim(req.body.email).toLowerCase();
    var pass = validator.trim(req.body.pass);
    var rePass = validator.trim(req.body.re_pass);

    var ep = new eventproxy();
    ep.fail(next);
    ep.on('prop_err', function(msg) {
        res.status(422);
        res.render('sign/signup', {
            error: msg,
            loginname: loginname,
            email: email
        });
    });

    var emailObj = S(email);
    var isAllowedDomainEmail = false;
    config.org_domains.forEach(function(d) {
        if (emailObj.contains('@' + d)) isAllowedDomainEmail = true
    });

    if (!isAllowedDomainEmail) {
        ep.emit('prop_err', '该邮箱不属于有效域名，不允许注册账号。');
        return;
    }


    // 验证信息的正确性
    if ([loginname, pass, rePass, email].some(function(item) {
            return item === '';
        })) {
        ep.emit('prop_err', '信息不完整。');
        return;
    }
    if (loginname.length < 5) {
        ep.emit('prop_err', '用户名至少需要5个字符。');
        return;
    }
    if (!tools.validateId(loginname)) {
        return ep.emit('prop_err', '用户名不合法。');
    }
    if (!validator.isEmail(email)) {
        return ep.emit('prop_err', '邮箱不合法。');
    }
    if (pass !== rePass) {
        return ep.emit('prop_err', '两次密码输入不一致。');
    }
    // END 验证信息的正确性


    User.getUsersByQuery({
        '$or': [{
            'loginname': loginname
        }, {
            'email': email
        }]
    }, {}, function(err, users) {
        if (err) {
            return next(err);
        }
        if (users.length > 0) {
            ep.emit('prop_err', '用户名或邮箱已被使用。');
            return;
        }

        tools.bhash(pass, ep.done(function(passhash) {
            // create gravatar
            var avatarUrl = User.makeGravatar(email);
            User.newAndSave(loginname, loginname, passhash, email, avatarUrl, false, function(err) {
                if (err) {
                    return next(err);
                }
                // 发送激活邮件
                mail.sendActiveMail(email, utility.md5(email + passhash + config.session_secret), loginname);
                res.render('sign/signup', {
                    success: '欢迎加入 ' + config.name + '！我们已给您的注册邮箱发送了一封邮件，请点击里面的链接来激活您的帐号。'
                });
            });

        }));
    });
};

/**
 * Show user login page.
 *
 * @param  {HttpRequest} req
 * @param  {HttpResponse} res
 */
exports.showLogin = function(req, res) {
    req.session._loginReferer = req.headers.referer;
    res.render('sign/signin');
};

/**
 * define some page when login just jump to the home page
 * @type {Array}
 */
var notJump = [
    '/active_account', //active page
    '/reset_pass', //reset password page, avoid to reset twice
    '/signup', //regist page
    '/search_pass' //serch pass page
];

/**
 * Handle user login.
 *
 * @param {HttpRequest} req
 * @param {HttpResponse} res
 * @param {Function} next
 */
exports.login = function(req, res, next) {
    console.log(req.body);
    var loginname = validator.trim(req.body.name).toLowerCase();
    var pass = validator.trim(req.body.pass);
    var device = req.body.device;

    var ep = new eventproxy();
    ep.fail(next);

    if (!loginname || !pass) {
        res.status(422);
        if (device == 'mobile') {
            return res.send({
                error: '信息不完整。'
            });
        } else {
            return res.render('sign/signin', {
                error: '信息不完整。'
            });
        }

    }

    var getUser;
    if (loginname.indexOf('@') !== -1) {
        getUser = User.getUserByMail;
    } else {
        getUser = User.getUserByLoginName;
    }

    ep.on('login_error', function(login_error) {
        res.status(403);
        if (device == 'mobile') {
            res.send({
                error: '用户名或密码错误'
            });
        } else {
            res.render('sign/signin', {
                error: '用户名或密码错误'
            });
        }
    });

    getUser(loginname, function(err, user) {
        if (err) {
            return next(err);
        }
        if (!user) {
            return ep.emit('login_error');
        }
        var passhash = user.pass;
        tools.bcompare(pass, passhash, ep.done(function(bool) {
            if (!bool) {
                return ep.emit('login_error');
            }
            if (!user.active) {
                // 重新发送激活邮件
                mail.sendActiveMail(user.email, utility.md5(user.email + passhash + config.session_secret), user.loginname);
                res.status(403);
                if (device == 'mobile') {
                    res.send({
                        error: '此帐号还没有被激活，激活链接已发送到 ' + user.email + ' 邮箱，请查收。'
                    });
                } else {
                    res.render('sign/signin', {
                        error: '此帐号还没有被激活，激活链接已发送到 ' + user.email + ' 邮箱，请查收。'
                    });
                }

            }
            // store session cookie
            authMiddleWare.gen_session(user, res);
            //check at some page just jump to home page
            var refer = req.session._loginReferer || '/';
            for (var i = 0, len = notJump.length; i !== len; ++i) {
                if (refer.indexOf(notJump[i]) >= 0) {
                    refer = '/';
                    break;
                }
            }
            if (device == 'mobile') {
                res.send({
                    rc: 1,
                    accessToken: user.accessToken
                });
            } else {
                res.redirect(refer);
            }
        }));
    });
};

// sign out
exports.signout = function(req, res, next) {
    req.session.destroy();
    res.clearCookie(config.auth_cookie_name, {
        path: '/'
    });
    res.redirect('/');
};

exports.active_account = function(req, res, next) {
    var key = req.query.key;
    var name = req.query.name;

    User.getUserByLoginName(name, function(err, user) {
        if (err) {
            return next(err);
        }
        var passhash = user.pass;
        if (!user || utility.md5(user.email + passhash + config.session_secret) !== key) {
            return res.render('notify/notify', {
                error: '信息有误，帐号无法被激活。'
            });
        }
        if (user.active) {
            return res.render('notify/notify', {
                error: '帐号已经是激活状态。'
            });
        }
        user.active = true;
        user.save(function(err) {
            if (err) {
                return next(err);
            }
            res.render('notify/notify', {
                success: '帐号已被激活，请登录'
            });
        });
    });
};

exports.showSearchPass = function(req, res) {
    res.render('sign/search_pass');
};

exports.updateSearchPass = function(req, res, next) {
    var email = validator.trim(req.body.email).toLowerCase();
    if (!validator.isEmail(email)) {
        return res.render('sign/search_pass', {
            error: '邮箱不合法',
            email: email
        });
    }

    // 动态生成retrive_key和timestamp到users collection,之后重置密码进行验证
    var retrieveKey = uuid.v4();
    var retrieveTime = new Date().getTime();
    User.getUserByMail(email, function(err, user) {
        if (!user) {
            res.render('sign/search_pass', {
                error: '没有这个电子邮箱。',
                email: email
            });
            return;
        }
        user.retrieve_key = retrieveKey;
        user.retrieve_time = retrieveTime;
        user.save(function(err) {
            if (err) {
                return next(err);
            }
            // 发送重置密码邮件
            mail.sendResetPassMail(email, retrieveKey, user.loginname);
            res.render('notify/notify', {
                success: '我们已给您填写的电子邮箱发送了一封邮件，请在24小时内点击里面的链接来重置密码。'
            });
        });
    });
};

/**
 * reset password
 * 'get' to show the page, 'post' to reset password
 * after reset password, retrieve_key&time will be destroy
 * @param  {http.req}   req
 * @param  {http.res}   res
 * @param  {Function} next
 */
exports.reset_pass = function(req, res, next) {
    var key = req.query.key;
    var name = req.query.name;
    User.getUserByNameAndKey(name, key, function(err, user) {
        if (!user) {
            res.status(403);
            return res.render('notify/notify', {
                error: '信息有误，密码无法重置。'
            });
        }
        var now = new Date().getTime();
        var oneDay = 1000 * 60 * 60 * 24;
        if (!user.retrieve_time || now - user.retrieve_time > oneDay) {
            res.status(403);
            return res.render('notify/notify', {
                error: '该链接已过期，请重新申请。'
            });
        }
        return res.render('sign/reset', {
            name: name,
            key: key
        });
    });
};

exports.update_pass = function(req, res, next) {
    var psw = validator.trim(req.body.psw) || '';
    var repsw = validator.trim(req.body.repsw) || '';
    var key = validator.trim(req.body.key) || '';
    var name = validator.trim(req.body.name) || '';
    var ep = new eventproxy();
    ep.fail(next);

    if (psw !== repsw) {
        return res.render('sign/reset', {
            name: name,
            key: key,
            error: '两次密码输入不一致。'
        });
    }
    User.getUserByNameAndKey(name, key, ep.done(function(user) {
        if (!user) {
            return res.render('notify/notify', {
                error: '错误的激活链接'
            });
        }
        tools.bhash(psw, ep.done(function(passhash) {
            user.pass = passhash;
            user.retrieve_key = null;
            user.retrieve_time = null;
            user.active = true; // 用户激活
            user.save(function(err) {
                if (err) {
                    return next(err);
                }
                return res.render('notify/notify', {
                    success: '你的密码已重置。'
                });
            });
        }));
    }));
};
